#include "forwardlist.h"
#include <malloc.h>
/*  函数功能：创建单链表,并返回
    return ：创建好的单链表 
*/
DYMFList DYMFListCreate()
{
    DYMFList ret = {
        .buff = NULL,
        .size = 0
    };
    return ret;
}

/*  函数功能：向链表 list 中添加一个元素 elem
    @param list: 待操作链表
    @param elem: 待添加的元素
    return ：操作成功返回1，失败返回0（有可能申请空间失败，或者其它情况导致插入失败，返回0）
*/
int DYMFListAdd(DYMFList *list, DYMFListDataType elem)
{
    int ret = 0;
    // 在下面填写你的代码
    if(list == NULL){
        return 0;
    }
    
    struct _list_node *tmp = (struct _list_node*)malloc(sizeof(struct _list_node));
    if(tmp == NULL){
        return 0;
    }
    
    /* 头插法建立链表 */
    tmp->data = elem;
    tmp->next = list->buff;
    list->buff = tmp;   

    list->size++;

    return ret;
}

/*  函数功能：从链表 list 中删除所有值为 elem 的元素
    @param list: 待操作链表
    @param elem: 待添加的元素
    @param equal: 因为要删除所有值为 elem 的元素，所以我们需要提供一个比较函数来比较 elem， equal 函数在 a == b时返回1，a != b 时返回 0, 若 equal 传入NULL，那么我们使用 == 来替代 equal 函数
    return ：操作成功返回1，失败返回0（链表可能并不存在该元素）
*/
int DYMFListDelete(DYMFList *list, DYMFListDataType elem, int (*equal)(DYMFListDataType *a, DYMFListDataType *b))
{
    int ret = 0;
    // 在下面填写你的代码
    if(list == NULL || list->size == 0) return 0;

    struct _list_node *prev = NULL, *curv = NULL; 

    /* 处理只有一个元素的情况 */
    if(list->size == 1)
    {
        if(equal(&list->buff->data, &elem))
        {
            ret = 1;
            free(list->buff);
            list->buff = NULL;
            list->size = 0;
        }
    /* 处理不止一个元素的情况 */
    }else{
        /* 先处理第二个元素以及以后的元素 */
        prev = list->buff;
        curv = list->buff->next;
        while(curv != NULL)
        {
            if(equal(&curv->data, &elem))
            {   
                struct _list_node *waitToFree = curv;
                curv = curv->next;
                prev->next = curv;
                free(waitToFree);
                ret = 1;        // 只要有 free(), 就会有 ret = 1
                list->size--;
            }else{
                prev = prev->next;
                curv = prev->next;
            }
        }

        /* 再处理第一个元素的情况 */
        if(equal(&list->buff->data, &elem))
        {
            struct _list_node *waitToFree = list->buff;
            list->buff = list->buff->next;
            list->size--;
            ret = 1;
            free(waitToFree);
        }
    }
    return ret;
}


/*  函数功能：查找链表 list 中是否有值为 elem 的元素
    @param list: 待操作链表
    @param elem: 待添加的元素
    @param equal: 因为要查找值为 elem 的元素，所以我们需要提供一个比较函数来比较 elem，equal 函数在 a == b 时返回 1，a != b 时返回 0, 若 equal 传入NULL，那么我们使用 == 来替代 equal 函数
    return ：操作成功返回 1 ，失败返回 0
*/
int DYMFListFind(DYMFList *list, DYMFListDataType elem, int (*equal)(DYMFListDataType *a, DYMFListDataType *b))
{
    int ret = 0;
    // 在下面填写你的代码
    if(list == NULL || list->size == 0) return 0;
    struct _list_node *tmp = list->buff;
    for(int i = 0; i < list->size; ++i)
    {
        if(tmp != NULL && equal(&elem, &tmp->data))
        {
            ret = 1;
            break;      // 找到后立即退出
        }else{
            tmp = tmp->next;
        }
    }
    
    return ret;
}

/*  函数功能：销毁单链表 list
    @param list: 待操作链表
*/
void DYMFListDectory(DYMFList *list)
{
    // 在下面填写你的代码
    if(list == NULL) return;
    if(list->buff == NULL){
        list->size = 0;
        return;
    }else{
        struct _list_node* tmp;
        for(int i = 0; i < list->size && list->buff != NULL; ++i){
            tmp = list->buff;
            list->buff = list->buff->next;
            free(tmp);
        }
        list->size = 0;
        list->buff = NULL;
    }
}

void DYMListForeach(DYMFList *list, void (*hook)(DYMFListDataType *elem))
{
    if(list == NULL || list->size == 0) return;
    
    struct _list_node *tmp = list->buff;
    for(int i = 0; i < list->size; ++i)
    {
        if(tmp != NULL && hook != NULL)
        {
            hook(&tmp->data);
            tmp = tmp->next;
        }else{
            break;
        }
    }
}